﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Code.Models
{
    [Serializable]
    public class NameValue<N,V>:IEnumerable<NameValueItem<N,V>>
    {
        private List<NameValueItem<N,V>> _Items;

        public NameValue()
        {
            _Items = new List<NameValueItem<N, V>>();
        }

        public void Add(NameValueItem<N, V> item)
        {
            if (item == null)
                throw new ArgumentNullException("item");
            this._Items.Add(item);
        }

        public void Add(N name, V value)
        {
            if (name == null||(name is string && string.IsNullOrEmpty(name as string)))
                throw new ArgumentNullException("name");

            this.Add(new NameValueItem<N, V>() { Key=name,Value=value});
        }

        public void AddRange(IEnumerable<NameValueItem<N, V>> collection)
        {
            this._Items.AddRange(collection);
        }

        public void Clear()
        {
            this._Items.Clear();
        }

        public void CopyTo(NameValueItem<N, V>[] array, int arrayIndex)
        {
            this._Items.CopyTo(array, arrayIndex);
        }

        public bool ContainsKey(N key)
        {
            return this._Items.Select(p => p.Key).Contains(key);
        }

        public bool ContainsValue(V value)
        {
            return this._Items.Select(p => p.Value).Contains(value);
        }

        public int Count
        {
            get { return this._Items.Count; }
        }

        public bool Remove(NameValueItem<N, V> item)
        {
            if (item == null)
                return false;
            else
                return this._Items.Remove(item);
        }

        public bool Remove(N name)
        {
            if (name == null)
                throw new ArgumentNullException("name");
            var tmp = this._Items.Where(p => p.Key.Equals(name)).FirstOrDefault();

            return this.Remove(tmp);
        }

        #region IEnumerable 成员

        IEnumerator IEnumerable.GetEnumerator()
        {
            return _Items.GetEnumerator();
        }

        #endregion

        #region IEnumerable<NameValueItem<N,V>> 成员

        IEnumerator<NameValueItem<N, V>> IEnumerable<NameValueItem<N, V>>.GetEnumerator()
        {
            return (this._Items as IEnumerable<NameValueItem<N, V>>).GetEnumerator();
        }

        #endregion
    }

    public class NameValueItemEqualseKey<N, V> : IEqualityComparer<NameValueItem<N, V>>
    {
        #region IEqualityComparer<NameValueItem<N,V>> 成员

        public bool Equals(NameValueItem<N, V> x, NameValueItem<N, V> y)
        {
            if (x == null && y == null)
                throw new ArgumentNullException();
            if (x.Key == null || y.Key == null)
                return x.Key == null && y.Key == null;

            return x.Key.Equals(y.Key);
        }

        public int GetHashCode(NameValueItem<N, V> obj)
        {
            if (obj == null || obj.Key == null)
                throw new ArgumentNullException();
            return obj.Key.GetHashCode();
        }

        #endregion
    }

    [Serializable]
    public class NameValueItem<N,V>
    {
        public N Key { get; set; }
        public V Value { get; set; }
    }
}